Skip to content

feat(nexus): add async, cancellation, failure and parallel features - #871

Open
xepozz wants to merge 3 commits into
temporalio:mainfrom
xepozz:feature/nexus-feature-set
Open

feat(nexus): add async, cancellation, failure and parallel features#871
xepozz wants to merge 3 commits into
temporalio:mainfrom
xepozz:feature/nexus-feature-set

Conversation

@xepozz

@xepozz xepozz commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Four Nexus scenarios implemented in Go and Java: an async workflow-run operation, cancelling a running async operation, a sync operation that fails with an application error, and three parallel sync operations.

What was changed

Why?

Checklist

  1. Closes

  2. How was this tested:

  1. Any docs updates needed?

Four Nexus scenarios implemented in Go and Java: an async workflow-run
operation, cancelling a running async operation, a sync operation that fails
with an application error, and three parallel sync operations.
@xepozz
xepozz requested review from a team as code owners August 19, 2026 06:11

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d5d438ca6c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

}
return runner.Client.ExecuteWorkflow(ctx, opts, Workflow, runner.NexusEndpoint)
},
CheckHistory: func(ctx context.Context, runner *harness.Runner, run client.WorkflowRun) error {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve default replay in Go history checks

When this feature runs, assigning CheckHistory replaces the harness path that calls Runner.CheckHistoryDefault (harness/go/harness/runner.go lines 151-157), so neither the current executions—including the backing workflow—nor stored histories are replayed. Run the default checker after the event assertion; the same omission occurs in the other three newly added Go Nexus features.

Useful? React with 👍 / 👎.

}

@Override
public void checkHistory(Runner runner, Run run) throws Exception {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve default replay in Java history checks

Overriding checkHistory here bypasses the default implementation in Feature.java, which calls runner.checkCurrentAndPastHistories(run). Consequently this feature never replay-checks its caller or backing workflow and cannot detect compatibility regressions against saved histories; invoke the default replay helper after the custom assertion. The other three new Java Nexus features have the same omission.

Useful? React with 👍 / 👎.

.getResult()
.handle(
(value, failure) -> {
resultHolder[0] = failure == null ? "completed" : "cancelled";

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Verify that the operation actually reports cancellation

When the operation result fails for any reason after scope.cancel()—for example a timeout or backing-workflow application failure—this callback labels it "cancelled", and the workflow plus history assertion still pass. Since the feature specifically promises to observe a cancellation error, inspect the failure chain for CanceledFailure rather than treating every non-null failure as cancellation.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good flag, in the Go test we do check for this already

The java handler threw a bare application failure, which the SDK reports as a
handler error, so the two languages were asserting different contracts.
.build();
TestService stub = Workflow.newNexusServiceStub(TestService.class, serviceOptions);

var resultHolder = new String[1];

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
var resultHolder = new String[1];
var resultHolder = Workflow.newPromise();

return OperationHandler.sync(
(context, details, name) -> {
throw OperationException.failure(
ApplicationFailure.newNonRetryableFailure("deliberate failure", "TestError"));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the Go test temporal.NewApplicationError(ErrorMessage, ErrorType) this will return a retry able application error

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The two tests should be consistent

@@ -0,0 +1,13 @@
# Nexus sync operation fails

A workflow invokes a synchronous Nexus operation that raises an application failure and

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Nexus operations you wrote do not "raises an application failure", they raise a OperationError. The OperationError happens to contain a application failure as a cause but from the SDKs perspective that is not relevant. What you have tested is fine, but I would correct the spec.

I'll note having a test where the Nexus operation DOES raise a application failure would also be a good test, but it doesn't have to be in this PR

@@ -0,0 +1,12 @@
# Nexus operations run in parallel

A workflow starts three synchronous Nexus operations in a single workflow task and awaits all

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please change the folder name to clarify this is parallel sync operations.

Keep the default history replay: the CheckHistory and checkHistory overrides
now call CheckHistoryDefault and checkCurrentAndPastHistories, which the
harness skips entirely when a feature supplies its own checker.

Assert the contracts the features claim instead of proxies for them: the java
caller looks for CanceledFailure in the cause chain rather than treating any
failure as cancellation, both languages assert the NexusOperationCanceled
event, and the parallel feature asserts that all three operations are
scheduled by a single workflow task.

Look up the application error by type rather than by cause-chain depth in both
languages, and fail with a diagnostic when it is missing. Raise a retryable
application error from the java handler so it matches the go one, and share
the type and message through constants.

Rename parallel_operations to parallel_sync_operations, align the workflow
results and error type between go and java, use CompletablePromise instead of
a mutable array in the java caller, and correct the sync_operation_error spec:
the handler raises an operation error that carries an application error as its
cause, not an application error directly.

nexus/sync_success gets the same replay fix so the whole nexus family behaves
alike; it is the only change outside the original diff of this PR.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants